#ifndef _AIO_MISC_H
#define _AIO_MISC_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdio.h>
#include <string.h>
#include <aio.h>
#include <pthread.h>
#include <rtems.h>
#include <rtems/chain.h>
#include <rtems/system.h>
#include <rtems/seterr.h>


  /* Various stages of a request */
  enum
  {
    AIO_NO,
    AIO_QUEUED,
    AIO_YES,
    AIO_ALLOCATED,
    AIO_DONE
  };

  /* Node containing a chain of requests having same FD */
  typedef struct rtems_aio_chain
  {

    rtems_chain_node next_fd;
    rtems_chain_control perfd;

    int fd;

  } rtems_aio_chain;

  /* Actual request being processed */
  typedef struct rtems_aio_request
  {

    rtems_chain_node next_prio; /* used in the perfd chain */
    rtems_chain_node next_buf;  /* used to keep track of free/used slots in req_pool */
    rtems_chain_node next_run;  /* used in runlist */
    rtems_chain_control waitlist;
    struct aiocb *aiocbp;

    int running;         /* stage of the request */
    pthread_t caller_thread;

  } rtems_aio_request;


  typedef struct rtems_aio_waitlist
  {

    rtems_chain_node next;
    rtems_chain_node async_next;
    int *result;
    volatile int *counterp;
    struct sigevent *sigevp;
    pthread_t caller_thread;
    pthread_cond_t *cond;

  } rtems_aio_waitlist;


  extern pthread_mutex_t aio_requests_mutex;

  extern rtems_aio_request *rtems_aio_enqueue_request (struct aiocb *aiocbp,
                                                 int operation);
  extern rtems_chain_node *rtems_aio_find_req (struct aiocb *aiocbp);
  extern rtems_chain_node *rtems_aio_find_fd (int fildes);
  extern void rtems_aio_remove_request (rtems_chain_node * last,
                                  rtems_chain_node * req, int all);
  extern void rtems_aio_free_request (rtems_aio_request * elem);

  extern void rtems_aio_notify (rtems_aio_request * req);
  extern int rtems_aio_notify_only (struct sigevent *sigev, pthread_t thid);

  extern int rtems_aio_init (const struct aioinit *init);
  extern void rtems_aio_debug (void);

#ifdef __cplusplus
}
#endif

#endif
